using VOL.demo.IRepositories;
using VOL.demo.IServices;
using VOL.Core.BaseProvider;
using VOL.Entity.DomainModels;
using VOL.Core.Utilities;
using System.Linq;
using VOL.Core.Extensions;

namespace VOL.demo.Services
{
    public partial class InventoryService
    {
        // Repository已在基类中注入，这里可以直接使用repository属性
        
        /// <summary>
        /// 添加库存信息
        /// </summary>
        /// <param name="inventory">库存信息</param>
        /// <returns></returns>
        public WebResponseContent AddInventory(InventoryModel inventory)
        {
            return repository.DbContextBeginTransaction(() =>
            {
                try
                {
                    // 验证必填字段
                    if (inventory.GoodsId <= 0)
                        return new WebResponseContent().Error("货品ID不能为空");
                    if (inventory.WarehouseId <= 0)
                        return new WebResponseContent().Error("仓库ID不能为空");
                    if (inventory.CurrentQty < 0)
                        return new WebResponseContent().Error("当前库存数量不能为负数");

                    // 检查是否已存在相同的库存记录
                    var existingInventory = repository.Find(x => x.GoodsId == inventory.GoodsId 
                        && x.WarehouseId == inventory.WarehouseId 
                        && x.BatchNo == inventory.BatchNo
                        && x.IsDel == 0).FirstOrDefault();
                    
                    if (existingInventory != null)
                    {
                        return new WebResponseContent().Error("该货品在该仓库中已存在相同批次的库存记录");
                    }

                    inventory.SetCreateDefaultVal();
                    inventory.IsDel = 0;
                    
                    // 设置初始库存数量
                    if (inventory.InitialQty == 0)
                        inventory.InitialQty = inventory.CurrentQty;

                    repository.Add(inventory, true);
                    
                    return new WebResponseContent().OK("库存信息添加成功", inventory);
                }
                catch (Exception ex)
                {
                    return new WebResponseContent().Error($"库存信息添加失败：{ex.Message}");
                }
            });
        }

        /// <summary>
        /// 批量添加库存信息
        /// </summary>
        /// <param name="inventories">库存列表</param>
        /// <returns></returns>
        public WebResponseContent BatchAddInventory(List<InventoryModel> inventories)
        {
            return repository.DbContextBeginTransaction(() =>
            {
                try
                {
                    foreach (var inventory in inventories)
                    {
                        // 验证必填字段
                        if (inventory.GoodsId <= 0 || inventory.WarehouseId <= 0 || inventory.CurrentQty < 0)
                        {
                            return new WebResponseContent().Error("存在无效的库存数据");
                        }

                        inventory.SetCreateDefaultVal();
                        inventory.IsDel = 0;
                        
                        // 设置初始库存数量
                        if (inventory.InitialQty == 0)
                            inventory.InitialQty = inventory.CurrentQty;
                    }

                    repository.AddRange(inventories, true);
                    return new WebResponseContent().OK("库存信息批量添加成功", inventories);
                }
                catch (Exception ex)
                {
                    return new WebResponseContent().Error($"库存信息批量添加失败：{ex.Message}");
                }
            });
        }

        /// <summary>
        /// 根据货品ID获取库存信息
        /// </summary>
        /// <param name="goodsId">货品ID</param>
        /// <returns></returns>
        public List<InventoryModel> GetInventoryByGoodsId(long goodsId)
        {
            return repository.Find(x => x.GoodsId == goodsId && x.IsDel == 0)
                .OrderByDescending(x => x.CreateDate)
                .ToList();
        }

        /// <summary>
        /// 根据仓库ID获取库存信息
        /// </summary>
        /// <param name="warehouseId">仓库ID</param>
        /// <returns></returns>
        public List<InventoryModel> GetInventoryByWarehouse(long warehouseId)
        {
            return repository.Find(x => x.WarehouseId == warehouseId && x.IsDel == 0)
                .OrderByDescending(x => x.CreateDate)
                .ToList();
        }

        /// <summary>
        /// 根据货品ID和仓库ID获取库存信息
        /// </summary>
        /// <param name="goodsId">货品ID</param>
        /// <param name="warehouseId">仓库ID</param>
        /// <returns></returns>
        public List<InventoryModel> GetInventoryByGoodsAndWarehouse(long goodsId, long warehouseId)
        {
            return repository.Find(x => x.GoodsId == goodsId 
                && x.WarehouseId == warehouseId 
                && x.IsDel == 0)
                .OrderByDescending(x => x.CreateDate)
                .ToList();
        }

        /// <summary>
        /// 根据批次号获取库存信息
        /// </summary>
        /// <param name="batchNo">批次号</param>
        /// <returns></returns>
        public List<InventoryModel> GetInventoryByBatchNo(string batchNo)
        {
            if (string.IsNullOrEmpty(batchNo))
                return new List<InventoryModel>();

            return repository.Find(x => x.BatchNo == batchNo && x.IsDel == 0)
                .OrderByDescending(x => x.CreateDate)
                .ToList();
        }

        /// <summary>
        /// 库存调整
        /// </summary>
        /// <param name="inventoryId">库存ID</param>
        /// <param name="adjustQuantity">调整数量（正数为增加，负数为减少）</param>
        /// <param name="reason">调整原因</param>
        /// <returns></returns>
        public WebResponseContent AdjustInventory(long inventoryId, int adjustQuantity, string reason)
        {
            return repository.DbContextBeginTransaction(() =>
            {
                try
                {
                    var inventory = repository.Find(x => x.Id == inventoryId && x.IsDel == 0).FirstOrDefault();
                    if (inventory == null)
                    {
                        return new WebResponseContent().Error("库存信息不存在");
                    }

                    var newQuantity = inventory.CurrentQty + adjustQuantity;
                    if (newQuantity < 0)
                    {
                        return new WebResponseContent().Error("调整后库存数量不能为负数");
                    }

                    inventory.CurrentQty = newQuantity;
                    inventory.SetModifyDefaultVal();
                    
                    // 如果有备注原因，更新备注
                    if (!string.IsNullOrEmpty(reason))
                    {
                        inventory.Remark = string.IsNullOrEmpty(inventory.Remark) 
                            ? $"库存调整：{reason}" 
                            : $"{inventory.Remark}；库存调整：{reason}";
                    }

                    repository.Update(inventory, true);
                    
                    string adjustType = adjustQuantity > 0 ? "增加" : "减少";
                    return new WebResponseContent().OK($"库存{adjustType}成功，当前库存：{newQuantity}");
                }
                catch (Exception ex)
                {
                    return new WebResponseContent().Error($"库存调整失败：{ex.Message}");
                }
            });
        }

        /// <summary>
        /// 更新库存信息
        /// </summary>
        /// <param name="inventory">库存信息</param>
        /// <returns></returns>
        public WebResponseContent UpdateInventory(InventoryModel inventory)
        {
            return repository.DbContextBeginTransaction(() =>
            {
                try
                {
                    var existingInventory = repository.Find(x => x.Id == inventory.Id && x.IsDel == 0).FirstOrDefault();
                    if (existingInventory == null)
                    {
                        return new WebResponseContent().Error("库存信息不存在");
                    }

                    // 验证必填字段
                    if (inventory.GoodsId <= 0)
                        return new WebResponseContent().Error("货品ID不能为空");
                    if (inventory.WarehouseId <= 0)
                        return new WebResponseContent().Error("仓库ID不能为空");
                    if (inventory.CurrentQty < 0)
                        return new WebResponseContent().Error("当前库存数量不能为负数");

                    // 更新字段
                    existingInventory.GoodsId = inventory.GoodsId;
                    existingInventory.WarehouseId = inventory.WarehouseId;
                    existingInventory.BatchNo = inventory.BatchNo;
                    existingInventory.CurrentQty = inventory.CurrentQty;
                    existingInventory.InitialQty = inventory.InitialQty;
                    existingInventory.UpperLimit = inventory.UpperLimit;
                    existingInventory.LowerLimit = inventory.LowerLimit;
                    existingInventory.ExpireDate = inventory.ExpireDate;
                    existingInventory.Remark = inventory.Remark;
                    existingInventory.SetModifyDefaultVal();

                    repository.Update(existingInventory, true);
                    return new WebResponseContent().OK("库存信息更新成功");
                }
                catch (Exception ex)
                {
                    return new WebResponseContent().Error($"库存信息更新失败：{ex.Message}");
                }
            });
        }

        /// <summary>
        /// 删除库存信息
        /// </summary>
        /// <param name="id">库存ID</param>
        /// <returns></returns>
        public WebResponseContent DeleteInventory(long id)
        {
            return repository.DbContextBeginTransaction(() =>
            {
                try
                {
                    var inventory = repository.Find(x => x.Id == id && x.IsDel == 0).FirstOrDefault();
                    if (inventory == null)
                    {
                        return new WebResponseContent().Error("库存信息不存在");
                    }

                    inventory.IsDel = 1;
                    inventory.SetModifyDefaultVal();
                    repository.Update(inventory, true);

                    return new WebResponseContent().OK("库存信息删除成功");
                }
                catch (Exception ex)
                {
                    return new WebResponseContent().Error($"库存信息删除失败：{ex.Message}");
                }
            });
        }

        /// <summary>
        /// 获取低库存预警信息
        /// </summary>
        /// <returns></returns>
        public List<InventoryModel> GetLowStockAlert()
        {
            return repository.Find(x => x.IsDel == 0 
                && x.LowerLimit.HasValue 
                && x.CurrentQty <= x.LowerLimit.Value)
                .OrderBy(x => x.CurrentQty)
                .ToList();
        }

        /// <summary>
        /// 获取即将过期的库存信息
        /// </summary>
        /// <param name="days">提前天数</param>
        /// <returns></returns>
        public List<InventoryModel> GetExpiringSoonInventory(int days)
        {
            var expireDate = DateTime.Now.AddDays(days);
            return repository.Find(x => x.ExpireDate <= expireDate 
                && x.ExpireDate >= DateTime.Now
                && x.IsDel == 0)
                .OrderBy(x => x.ExpireDate)
                .ToList();
        }

        /// <summary>
        /// 批量设置库存上下限
        /// </summary>
        /// <param name="inventoryIds">库存ID列表</param>
        /// <param name="upperLimit">库存上限</param>
        /// <param name="lowerLimit">库存下限</param>
        /// <returns></returns>
        public WebResponseContent BatchSetInventoryLimits(List<long> inventoryIds, int? upperLimit, int? lowerLimit)
        {
            return repository.DbContextBeginTransaction(() =>
            {
                try
                {
                    var inventories = repository.Find(x => inventoryIds.Contains(x.Id) && x.IsDel == 0).ToList();
                    if (inventories.Count == 0)
                    {
                        return new WebResponseContent().Error("未找到有效的库存信息");
                    }

                    foreach (var inventory in inventories)
                    {
                        if (upperLimit.HasValue)
                            inventory.UpperLimit = upperLimit.Value;
                        if (lowerLimit.HasValue)
                            inventory.LowerLimit = lowerLimit.Value;
                        
                        inventory.SetModifyDefaultVal();
                    }

                    repository.UpdateRange(inventories, true);
                    return new WebResponseContent().OK($"成功设置{inventories.Count}条库存的上下限");
                }
                catch (Exception ex)
                {
                    return new WebResponseContent().Error($"批量设置库存上下限失败：{ex.Message}");
                }
            });
        }

        /// <summary>
        /// 获取库存统计信息
        /// </summary>
        /// <param name="warehouseId">仓库ID（可选）</param>
        /// <returns></returns>
        public object GetInventoryStatistics(long? warehouseId)
        {
            try
            {
                var inventories = warehouseId.HasValue
                    ? repository.Find(x => x.IsDel == 0 && x.WarehouseId == warehouseId.Value).ToList()
                    : repository.Find(x => x.IsDel == 0).ToList();
                
                var statistics = new
                {
                    TotalItems = inventories.Count,
                    TotalQuantity = inventories.Sum(x => x.CurrentQty),
                    LowStockCount = inventories.Count(x => x.LowerLimit.HasValue && x.CurrentQty <= x.LowerLimit.Value),
                    ExpiringSoonCount = inventories.Count(x => x.ExpireDate.HasValue && x.ExpireDate <= DateTime.Now.AddDays(30)),
                    OverStockCount = inventories.Count(x => x.UpperLimit.HasValue && x.CurrentQty >= x.UpperLimit.Value),
                    ZeroStockCount = inventories.Count(x => x.CurrentQty == 0),
                    AverageQuantity = inventories.Count > 0 ? inventories.Average(x => x.CurrentQty) : 0
                };

                return statistics;
            }
            catch (Exception ex)
            {
                throw new Exception($"获取库存统计信息失败：{ex.Message}");
            }
        }
    }
}
